using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace SqlTools.SchemaReader.UI
{
	public partial class Main : Form
	{
		protected string _connString = "";
		protected string _dbName = "";

		protected Database _database = null;

		public Main()
		{
			InitializeComponent();
		}

		private void exitToolStripMenuItem_Click(object sender, EventArgs e)
		{
			this.Close();
		}

		private void connectToolStripMenuItem_Click(object sender, EventArgs e)
		{
			SqlTools.Utility.Windows.ConnectToDB connect = new SqlTools.Utility.Windows.ConnectToDB();

			if ( connect.ShowDialog() == DialogResult.OK )
			{
				// connect and load meta data
				saveSchemaToolStripMenuItem.Enabled = true;
				viewRelationshipsToolStripMenuItem.Enabled = true;
				_connString = connect.ConnectionString;
				_dbName = connect.DbName;
				LoadData();
			}
		}

		private void LoadData()
		{
			Database db = new Database(_dbName);

			_database = db;

			db.LoadMetadata(_connString);

			BuildTree();
		}

		protected void BuildTree()
		{
			Database db = _database;

			tvwSchema.Nodes.Clear();

			TreeNode tnTables = tvwSchema.Nodes.Add("Tables");
			TreeNode tnViews = tvwSchema.Nodes.Add("Views");
			TreeNode tnSprocs = tvwSchema.Nodes.Add("Stored Procedures");

			// add info to tree
			foreach ( Table table in db.Tables )
			{
				TreeNode tnTable = tnTables.Nodes.Add(table.Name);

				TreeNode tnPKs = tnTable.Nodes.Add("PrimaryKey");
				TreeNode tnColumns = tnTable.Nodes.Add("Columns");
				TreeNode tnFKs = tnTable.Nodes.Add("Foreign Keys");
				TreeNode tnIndexes = tnTable.Nodes.Add("Indexes");

				foreach ( Column column in table.Columns )
				{

					TreeNode tnColumn = tnColumns.Nodes.Add(CreateColumnName(column));

					if ( column.Check != null )
					{
						tnColumn.Nodes.Add("Check: " + column.Check.Text + " <" + column.Check.Name + ">");
					}

					if ( column.Default != null )
					{
						tnColumn.Nodes.Add("Default: " + column.Default.Text + " <" + column.Default.Name + ">");
					}
				}

				if ( table.PrimaryKey != null )
				{
					foreach ( Column column in table.PrimaryKey.Columns )
					{
						tnPKs.Nodes.Add(CreateColumnName(column));
					}
				}

				foreach ( ForeignKey fk in table.ForeignKeys )
				{
					TreeNode tnFK = tnFKs.Nodes.Add(fk.Name);

					tnFK.Nodes.Add("Reference Table: " + fk.ReferenceTable.Name);
					tnFK.Nodes.Add("Reference Column: " + fk.ReferenceColumn.Name);
					tnFK.Nodes.Add("ForeignKey Table: " + fk.ForeignKeyTable.Name);
					tnFK.Nodes.Add("ForeignKey Column: " + fk.ForeignKeyColumn.Name);
				}

				foreach ( Index index in table.Indexes )
				{
					TreeNode tnIndex = tnIndexes.Nodes.Add(index.Name);

					foreach ( Column column in index.Columns )
					{
						tnIndex.Nodes.Add(CreateColumnName(column));
					}
				}
			}

			foreach ( View view in db.Views )
			{
				TreeNode tnView = tnViews.Nodes.Add(view.Name);

				tnView.Nodes.Add("Text").Nodes.Add(view.Text);

				TreeNode tnColumns = tnView.Nodes.Add("Columns");
				foreach ( Column column in view.Columns )
				{
					tnColumns.Nodes.Add(CreateColumnName(column));
				}
			}

			foreach ( StoredProcedure sp in db.StoredProcedures )
			{
				TreeNode tnSP = tnSprocs.Nodes.Add(sp.Name);

				tnSP.Nodes.Add("Text").Nodes.Add(sp.Text);

				TreeNode tnParams = tnSP.Nodes.Add("Parameters");

				foreach ( Parameter param in sp.Parameters )
				{
					tnParams.Nodes.Add(CreateParameterName(param));
				}
			}
		}

		protected string CreateParameterName(Parameter param)
		{
			string pName = param.Name;

			pName += " <" + param.DataType + ", " + param.Length + ">";

			if ( param.IsComputed )
				pName += ", CP";
			if ( param.IsOutput )
				pName += ", OUTPUT";
			if ( param.IsNullable )
				pName += " NULL";
			else
				pName += " NOT NULL";

			return pName;
		}

		protected string CreateColumnName(Column column)
		{
			string colName = column.Name;

			colName += " <" + column.DataType + ", " + column.Length + ">";

			if ( column.IsComputed )
				colName += ", CP";
			if ( column.IsForeignKey )
				colName += ", FK";
			if ( column.IsIdentity )
				colName += ", ID";
			if ( column.IsPrimaryKey )
				colName += ", PK";
			if ( column.IsNullable )
				colName += " NULL";
			else
				colName += " NOT NULL";

			return colName;
		}

		private void saveSchemaToolStripMenuItem_Click(object sender, EventArgs e)
		{
			if ( _database != null )
			{
				if ( saveFileDialog1.ShowDialog() == DialogResult.OK )
				{
					string filename = saveFileDialog1.FileName;

					_database.Save(filename);
				}
			}
		}

		private void loadSchemaToolStripMenuItem_Click(object sender, EventArgs e)
		{
			if ( openFileDialog1.ShowDialog() == DialogResult.OK )
			{
				string filename = openFileDialog1.FileName;

				_database = new Database();

				_database.Load(filename);

				BuildTree();
			}
		}

		private void viewRelationshipsToolStripMenuItem_Click(object sender, EventArgs e)
		{
			Relationships rel = new Relationships();

			rel.Database = _database;

			rel.LoadRelationships();

			rel.ShowDialog();
		}
	}
}